/*
 * CastBooleanAst.cpp
 *
 *  Created on: 19 Nov 2010
 *      Author: kn308
 */
#include <sstream>

#include <MAlice/Parser/location.hh>
#include <MAlice/Ast/CastBooleanAst.h>
#include <MAlice/Ast/IntegerLiteralAst.h>
#include <MAlice/Codegen.h>

namespace MAlice
{

CastBooleanAst::CastBooleanAst(location loc, ExpressionAst* value) : ExpressionAst(loc),
	mValue(value)
{
	MALICE_TRACE;
}

CastBooleanAst::~CastBooleanAst()
{
	MALICE_TRACE;
}

llvm::Value* CastBooleanAst::generate()
{
	MALICE_TRACE;

	Codegen* g       = Codegen::get();
	Builder* builder = g->getBuilder();

	Value* value = mValue->generate();
	const Type* type = value->getType();
	;

	if (type->isPointerTy())
	{
		// XXX assume sentence
		return builder->CreateIsNotNull(value, "<cast>bool");
	}
	else if (type->isIntegerTy())
	{
		if (type->isIntegerTy(1))
		{
			return value;
		}
		else
		{
			// bit cast to i32
			value = builder->CreateBitCast(value, Type::getInt32Ty(g->getContext()));

			// compare with i32 0
			return builder->CreateICmpNE(value, IntegerLiteralAst(mLocation, 0).generate(), "<cast>bool");
		}
	}
	else
	{
		stringstream ss;
		ss << "Value (" << mLocation << ") has unrecognisable type for boolean conversion '";
		ss << g->getModule()->getTypeName(type) << "'";
		throw runtime_error(ss.str());
	}
}

}
